/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package data;

import base.Download;
import exception.RepositoryException;
import base.Task;
import base.WeekDays;
import exception.TaskExistsException;
import exception.TaskNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;



/**
 *
 * @author tacio
 */
public class TaskRepositoryXml implements ITaskRepository {

    private SAXBuilder sb;
    private Document xmlDoc;
    private Element rootElement;


    public TaskRepositoryXml() throws RepositoryException {
        try {
            this.sb = new SAXBuilder();
            URL tasksXmlUrl = this.getClass().getResource("/resources/Tasks.xml");
//            InputStream tasksXml = TaskRepositoryXml.class.getResourceAsStream("/resources/Tasks.xml");
            this.xmlDoc = sb.build(tasksXmlUrl);
            this.rootElement = xmlDoc.getRootElement();
        } catch (JDOMException ex) {
            throw new RepositoryException(ex.getMessage());
        } catch (IOException ex) {
            throw new RepositoryException(ex.getMessage());
        }
    }

    public void add(Task task) throws RepositoryException, TaskExistsException {
        Element taskElement = new Element("task");
        taskElement.setAttribute(new Attribute("name", task.getName()));
        taskElement.setAttribute(new Attribute("searchString", task.getSearchString()));
        taskElement.setAttribute(new Attribute("initialEpisode", task.getInitialEpisode()));

        //transforma o ArrayList<WeekDays> para uma string "dia1 dia2"
        String schedule = new String();
        for (WeekDays weekDay : task.getSchedule()) {
            schedule += weekDay + " ";
        }
        taskElement.setAttribute(new Attribute("schedule", schedule.trim()));
        taskElement.setAttribute(new Attribute("resolution", task.getResolution()));
        taskElement.setAttribute(new Attribute("distribution", task.getDistribution()));
        taskElement.setAttribute(new Attribute("url", task.getUrl()));
        Element downloads = new Element("downloads");
        taskElement.addContent(downloads);

        try {
            rootElement.addContent(taskElement);
            xmlDoc.setRootElement(rootElement);
            XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
            URL tasksXml = TaskRepositoryXml.class.getResource("/resources/Tasks.xml");
            URI tasksXmlURI = tasksXml.toURI();
            System.out.println(tasksXmlURI.getPath());
            outputter.output(xmlDoc, new FileWriter(tasksXmlURI.getPath()));
        } catch (URISyntaxException ex) {
            Logger.getLogger(TaskRepositoryXml.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            throw new RepositoryException(ex.getMessage());
        }
    }

    public void remove(String taskName) throws RepositoryException, TaskNotFoundException {

        try {
            List<Element> taskList = rootElement.getChildren("task");

            for (Element element : taskList) {
                if (element.getAttributeValue("name").equals(taskName)) {
                    rootElement.removeContent(element);
                    xmlDoc.setContent(rootElement);
                    break;
                }
            }
            XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
            URL tasksXml = TaskRepositoryXml.class.getResource("/resources/Tasks.xml");
            URI tasksXmlURI = tasksXml.toURI();
            outputter.output(xmlDoc, new FileWriter(tasksXmlURI.getPath()+tasksXmlURI.getQuery()));
        } catch (URISyntaxException ex) {
            Logger.getLogger(TaskRepositoryXml.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            throw new RepositoryException(ex.getMessage());
        }

    }

    public void update(Task task) throws RepositoryException, TaskNotFoundException {


        try {
            remove(task.getName());

            Element taskElement = new Element("task");
            taskElement.setAttribute(new Attribute("name", task.getName()));
            taskElement.setAttribute(new Attribute("searchString", task.getSearchString()));
            taskElement.setAttribute(new Attribute("searchString", task.getSearchString()));
            taskElement.setAttribute(new Attribute("resolution", task.getResolution()));
            taskElement.setAttribute(new Attribute("distribution", task.getDistribution()));

            //transforma o ArrayList<WeekDays> para uma string "dia1 dia2"
            String schedule = new String();
            for (WeekDays weekDay : task.getSchedule()) {
                schedule += weekDay + " ";
            }
            taskElement.setAttribute(new Attribute("schedule", schedule.trim()));

            taskElement.setAttribute(new Attribute("url", task.getUrl()));
            Element downloadsElement = new Element("downloads");
            if (task.getDownloads() != null) {
                ArrayList<Download> downloads = task.getDownloads();
                for (Download download : downloads) {
                    Element newDownload = new Element("download");
                    newDownload.setAttribute("date", download.getDate());
                    newDownload.setAttribute("torrentName", download.getTorrentName());
                    downloadsElement.addContent(newDownload);
                }

            }
            taskElement.addContent(downloadsElement);
            rootElement.addContent(taskElement);
            xmlDoc.setContent(rootElement);
            XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
            URL tasksXml = TaskRepositoryXml.class.getResource("/resources/Tasks.xml");
            URI tasksXmlURI = tasksXml.toURI();
            outputter.output(xmlDoc, new FileWriter(tasksXmlURI.getPath()+tasksXmlURI.getQuery()));

        } catch (URISyntaxException ex) {
            Logger.getLogger(TaskRepositoryXml.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            throw new RepositoryException(ex.getMessage());
        }

    }

    public Task search(String taskName) throws RepositoryException {

        Task taskFound = null;

        List<Element> taskList = rootElement.getChildren();
        for (Element element : taskList) {
            if (element.getAttributeValue("name").equals(taskName)) {
                taskFound = new Task(element.getAttributeValue("name"),
                        element.getAttributeValue("searchString"), element.getAttributeValue("url"));
                taskFound.setDistribution(element.getAttributeValue("distribution"));
                taskFound.setInitialEpisode(element.getAttributeValue("initialEpisode"));
                taskFound.setResolution(element.getAttributeValue("resolution"));

                //transforma a string de schedule no format [dia1, dia2] em um ArrayList<WeekDays>
                String schedule = element.getAttributeValue("schedule");
                String[] scheduleList = schedule.split(" ");
                ArrayList<WeekDays> scheduleArray = new ArrayList<WeekDays>();
                for (String weekDay : scheduleList) {
                    scheduleArray.add(WeekDays.valueOf(weekDay));
                }
                taskFound.setSchedule(scheduleArray);
                //--------------------------------------------------------------------------------------


                Element downloadList = element.getChild("downloads");
                if (downloadList != null) {
                    List<Element> downloadedTorrentList = downloadList.getChildren("download");
                    ArrayList<Download> downloads = new ArrayList<Download>();
                    for (Element downElement : downloadedTorrentList) {
                        Download download = new Download(downElement.getAttributeValue("torrentName"));
                        download.setDate(downElement.getAttributeValue("date"));
                        downloads.add(download);
                    }
                    taskFound.setDownloads(downloads);
                }
            }
        }
        return taskFound;
    }

    public ArrayList<String[]> getTaskList() throws RepositoryException {
        ArrayList<String[]> taskArray = new ArrayList<String[]>();
        List<Element> taskList = rootElement.getChildren();
        if (taskList != null) {
            taskArray = new ArrayList<String[]>();
            for (Element task : taskList) {
                taskArray.add(new String[]{task.getAttributeValue("name"), task.getAttributeValue("searchString"),
                            task.getAttributeValue("url"), task.getAttributeValue("schedule")});
            }
        }
        return taskArray;
    }

    public boolean downloadExists(Task task, URL torrentURL) throws RepositoryException {

        ArrayList<Download> downloads = task.getDownloads();
        boolean exists = false;
        if (downloads != null) {
            for (Download download : downloads) {
                if (download.getTorrentName().equals(torrentURL.toString())) {
                    exists = true;
                }
            }
        }
        return exists;
    }

    public ArrayList<String[]> getDownloadList() throws RepositoryException {
        ArrayList<String[]> downloadArray = new ArrayList<String[]>();
        List<Element> taskList = rootElement.getChildren();
        if (taskList != null) {
            for (Element task : taskList) {
                List<Element> downloadList = task.getChild("downloads").getChildren();
                if (downloadList != null) {
                    for (Element download : downloadList) {
                        downloadArray.add(new String[]{task.getAttributeValue("name"), download.getAttributeValue("date"),
                                    download.getAttributeValue("torrentName")});
                    }
                }
            }
        }
        return downloadArray;
    }
}

